package org.gpp.proj1.logic.profile.manager;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

import org.gpp.proj1.logic.profile.PlayerProfile;

import com.jme.util.LoggingSystem;

/**
 * Class that stores an reads player profiles
 * 
 * @author Paolo Victor, paolovictor@gmail.com
 */
public class ProfileManager {
	private Map<String, PlayerProfile> profiles;
	
	private String profilesFile;
	
	public ProfileManager() {
		this.profiles = new HashMap<String, PlayerProfile>();
	}
	
	/**
	 * Creates a new profile manager, loading a profiles file
	 * 
	 * @param profilesFile The profiles file path
	 * @throws ProfileManagerException If the profiles could not be loaded
	 */
	public ProfileManager( String profilesFile ) throws ProfileManagerException {
		this.profilesFile = profilesFile;
		this.loadProfiles();
	}

	/**
	 * Loads the player profiles 
	 * 
	 * @throws ProfileManagerException If the profiles could not be loaded
	 */
	private void loadProfiles() throws ProfileManagerException {
		File file = new File( profilesFile );
		
		if( ! file.exists() ) {			
			LoggingSystem.getLogger().warning( "File not found: \"" + profilesFile + "\". " +
					"Creating new profiles file." );
			this.profiles = new HashMap<String, PlayerProfile>();
			return;
		}
		
		ObjectInputStream in = null;
		try {
			in = new ObjectInputStream( new FileInputStream( file ) );
			
			this.profiles = (Map<String, PlayerProfile>) in.readObject();
		} catch (FileNotFoundException e) {
			throw new ProfileManagerException( "Can't load profiles file", e );
		} catch (IOException e) {
			throw new ProfileManagerException( "Can't load profiles file", e );
		} catch (ClassNotFoundException e) {
			throw new ProfileManagerException( "Can't load profiles file", e );
		} finally {
			if( in != null ) {
				try {
					in.close();
				} catch (IOException e) {}
			}
		}
	}
	
	/**
	 * Saves the profiles to the profiles file
	 * @throws ProfileManagerException If the profiles could not be saved
	 */
	public void saveProfiles() throws ProfileManagerException {
		File file = new File( profilesFile );
		
		ObjectOutputStream out = null;
		try {
			out = new ObjectOutputStream( new FileOutputStream( file ) );			
			out.writeObject( profiles );
		} catch (FileNotFoundException e) {
			throw new ProfileManagerException( "Can't save profiles file", e );
		} catch (IOException e) {
			throw new ProfileManagerException( "Can't save profiles file", e );
		} finally {
			if( out != null ) {
				try {
					out.close();
				} catch (IOException e) {}
			}
		}
	}
	
	/**
	 * Add a profile to the profiles list
	 * @param profile
	 */
	public void addProfile( PlayerProfile profile ) {
		if( profile == null ) {
			throw new IllegalArgumentException( "Invalid profile" );
		}
		
		profiles.put( profile.getName(), profile );
	}
	
	/**
	 * @param playerName
	 * @return The profile for the given player name
	 */
	public PlayerProfile getProfile( String playerName ) {
		
		if( ! profiles.containsKey( playerName ) ) {
			throw new IllegalArgumentException("There's no such profile");
		}
		
		return profiles.get( playerName );
	}

	/**
	 * @return All the player names that have stored profiles
	 */
	public Set<String> getPlayerProfileNames() {
		
		return profiles.keySet();
	}

	/**
	 * Updates a player profile
	 * @param profile
	 */
	public void updateProfile(PlayerProfile profile) {

		if( ! profiles.containsKey( profile.getName() ) ) {
			throw new IllegalArgumentException("There's no such profile");
		}
		
		profiles.put( profile.getName(), profile );
	}
}
